# =====================================================
# 后端 API 测试脚本
# =====================================================
# 基础 URL: http://localhost:8080/api/v1
# 执行方式: .\test-api.ps1
# =====================================================

$baseUrl = "http://localhost:8080/doc/api/v1"
$token = $null

# 颜色输出函数
function Write-Success { param($msg) Write-Host "✅ $msg" -ForegroundColor Green }
function Write-Error { param($msg) Write-Host "❌ $msg" -ForegroundColor Red }
function Write-Info { param($msg) Write-Host "ℹ️  $msg" -ForegroundColor Cyan }
function Write-Section { param($msg) Write-Host "`n========================================" -ForegroundColor Yellow; Write-Host $msg -ForegroundColor Yellow; Write-Host "========================================" -ForegroundColor Yellow }

# HTTP 请求函数
function Invoke-ApiRequest {
    param(
        [string]$Uri,
        [string]$Method = "GET",
        [object]$Body = $null,
        [string]$Token = $null
    )
    
    try {
        $headers = @{
            "Content-Type" = "application/json"
        }
        
        if ($Token) {
            $headers["Authorization"] = "Bearer $Token"
        }
        
        $params = @{
            Uri = $Uri
            Method = $Method
            Headers = $headers
        }
        
        if ($Body) {
            $params["Body"] = ($Body | ConvertTo-Json -Depth 10)
        }
        
        $response = Invoke-RestMethod @params
        return @{ Success = $true; Data = $response }
    }
    catch {
        $statusCode = $_.Exception.Response.StatusCode.value__
        $statusDesc = $_.Exception.Response.StatusDescription
        return @{ Success = $false; StatusCode = $statusCode; Error = $statusDesc; Exception = $_ }
    }
}

Write-Section "开始测试后端 API"
Write-Info "基础 URL: $baseUrl"
Write-Info "时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"

# =====================================================
# 1. 测试认证接口
# =====================================================
Write-Section "1. 认证接口测试"

# 1.1 登录
Write-Info "测试: POST /auth/login (管理员)"
$loginBody = @{
    email = "admin@example.com"
    password = "password"
}

$result = Invoke-ApiRequest -Uri "$baseUrl/auth/login" -Method POST -Body $loginBody

if ($result.Success) {
    Write-Success "登录成功"
    $token = $result.Data.accessToken
    if ($token) {
        Write-Info "Access Token: $($token.Substring(0, [Math]::Min(50, $token.Length)))..."
        Write-Info "Token Type: $($result.Data.tokenType)"
        Write-Info "Expires In: $($result.Data.expiresIn) 秒"
        Write-Info "用户: $($result.Data.user.username) ($($result.Data.user.roleName))"
    } else {
        Write-Info "Token: $($result.Data)"
    }
}
else {
    Write-Error "登录失败 (Status: $($result.StatusCode))"
    Write-Info "可能原因: CSRF 保护、Spring Security 配置、密码哈希不匹配"
    Write-Info "建议检查后端日志"
}

# 1.2 测试编辑用户登录
Write-Info "`n测试: POST /auth/login (编辑用户)"
$editorLoginBody = @{
    email = "editor@example.com"
    password = "password"
}

$editorResult = Invoke-ApiRequest -Uri "$baseUrl/auth/login" -Method POST -Body $editorLoginBody

if ($editorResult.Success) {
    Write-Success "编辑用户登录成功"
}
else {
    Write-Error "编辑用户登录失败 (Status: $($editorResult.StatusCode))"
}

# =====================================================
# 2. 测试文档分类接口
# =====================================================
Write-Section "2. 文档分类接口测试"

# 2.1 获取分类列表
Write-Info "测试: GET /categories"
$categoriesResult = Invoke-ApiRequest -Uri "$baseUrl/categories" -Method GET -Token $token

if ($categoriesResult.Success) {
    Write-Success "获取分类列表成功"
    $categories = $categoriesResult.Data
    if ($categories.data) {
        Write-Info "分类总数: $($categories.data.Count)"
        Write-Info "根分类:"
        $categories.data | Where-Object { -not $_.parentId } | ForEach-Object {
            Write-Host "  - [$($_.id)] $($_.name) ($($_.slug))" -ForegroundColor Gray
        }
    }
}
else {
    Write-Error "获取分类列表失败 (Status: $($categoriesResult.StatusCode))"
}

# 2.2 获取分类树
Write-Info "`n测试: GET /categories/tree"
$treeResult = Invoke-ApiRequest -Uri "$baseUrl/categories/tree" -Method GET -Token $token

if ($treeResult.Success) {
    Write-Success "获取分类树成功"
}
else {
    Write-Error "获取分类树失败 (Status: $($treeResult.StatusCode))"
}

# =====================================================
# 3. 测试文档接口
# =====================================================
Write-Section "3. 文档接口测试"

# 3.1 获取文档列表
Write-Info "测试: GET /documents?page=1&size=10"
$docsResult = Invoke-ApiRequest -Uri "$baseUrl/documents?page=1&size=10" -Method GET -Token $token

if ($docsResult.Success) {
    Write-Success "获取文档列表成功"
    $docs = $docsResult.Data
    if ($docs.data) {
        Write-Info "文档总数: $($docs.total)"
        Write-Info "当前页: $($docs.page) / $($docs.totalPages)"
        Write-Info "文档列表:"
        $docs.data | ForEach-Object {
            Write-Host "  - [$($_.id)] $($_.title) ($($_.slug)) - $($_.status)" -ForegroundColor Gray
        }
    }
}
else {
    Write-Error "获取文档列表失败 (Status: $($docsResult.StatusCode))"
}

# 3.2 根据分类获取文档
Write-Info "`n测试: GET /documents?categoryId=6"
$catDocsResult = Invoke-ApiRequest -Uri "$baseUrl/documents?categoryId=6" -Method GET -Token $token

if ($catDocsResult.Success) {
    Write-Success "根据分类获取文档成功"
    Write-Info "文档数: $($catDocsResult.Data.total)"
}
else {
    Write-Error "根据分类获取文档失败 (Status: $($catDocsResult.StatusCode))"
}

# 3.3 获取文档详情（通过 slug）
Write-Info "`n测试: GET /documents/rest-api-quick-start"
$docDetailResult = Invoke-ApiRequest -Uri "$baseUrl/documents/rest-api-quick-start" -Method GET -Token $token

if ($docDetailResult.Success) {
    Write-Success "获取文档详情成功"
    $doc = $docDetailResult.Data.data
    Write-Info "标题: $($doc.title)"
    Write-Info "作者: $($doc.authorName)"
    Write-Info "浏览数: $($doc.viewCount)"
    Write-Info "点赞数: $($doc.likeCount)"
}
else {
    Write-Error "获取文档详情失败 (Status: $($docDetailResult.StatusCode))"
}

# =====================================================
# 4. 测试创建文档（需要权限）
# =====================================================
Write-Section "4. 文档创建测试"

Write-Info "测试: POST /documents (创建新文档)"
$newDoc = @{
    title = "API 测试文档"
    slug = "api-test-document-" + (Get-Date -Format "yyyyMMddHHmmss")
    summary = "这是通过 API 测试创建的文档"
    content = "# API 测试文档`n`n这是测试内容。"
    contentType = "direct"
    categoryId = 6
    tags = @("测试", "API")
    isPublic = $true
    status = "draft"
}

$createResult = Invoke-ApiRequest -Uri "$baseUrl/documents" -Method POST -Body $newDoc -Token $token

if ($createResult.Success) {
    Write-Success "创建文档成功"
    $createdDoc = $createResult.Data.data
    Write-Info "文档 ID: $($createdDoc.id)"
    Write-Info "Slug: $($createdDoc.slug)"
    
    # 4.1 更新文档
    Write-Info "`n测试: PUT /documents/$($createdDoc.id) (更新文档)"
    $updateDoc = @{
        title = "API 测试文档 (已更新)"
        summary = "这是更新后的摘要"
        status = "published"
    }
    
    $updateResult = Invoke-ApiRequest -Uri "$baseUrl/documents/$($createdDoc.id)" -Method PUT -Body $updateDoc -Token $token
    
    if ($updateResult.Success) {
        Write-Success "更新文档成功"
    }
    else {
        Write-Error "更新文档失败 (Status: $($updateResult.StatusCode))"
    }
    
    # 4.2 删除文档
    Write-Info "`n测试: DELETE /documents/$($createdDoc.id) (删除文档)"
    $deleteResult = Invoke-ApiRequest -Uri "$baseUrl/documents/$($createdDoc.id)" -Method DELETE -Token $token
    
    if ($deleteResult.Success) {
        Write-Success "删除文档成功"
    }
    else {
        Write-Error "删除文档失败 (Status: $($deleteResult.StatusCode))"
    }
}
else {
    Write-Error "创建文档失败 (Status: $($createResult.StatusCode))"
}

# =====================================================
# 5. 测试用户接口（管理员权限）
# =====================================================
Write-Section "5. 用户管理接口测试"

Write-Info "测试: GET /users?page=1&size=10"
$usersResult = Invoke-ApiRequest -Uri "$baseUrl/users?page=1&size=10" -Method GET -Token $token

if ($usersResult.Success) {
    Write-Success "获取用户列表成功"
    $users = $usersResult.Data
    if ($users.data) {
        Write-Info "用户总数: $($users.total)"
        Write-Info "用户列表:"
        $users.data | ForEach-Object {
            Write-Host "  - $($_.username) ($($_.email)) - $($_.roleName)" -ForegroundColor Gray
        }
    }
}
else {
    Write-Error "获取用户列表失败 (Status: $($usersResult.StatusCode))"
    Write-Info "可能需要管理员权限"
}

# =====================================================
# 6. 测试角色和权限接口
# =====================================================
Write-Section "6. 角色权限接口测试"

Write-Info "测试: GET /roles"
$rolesResult = Invoke-ApiRequest -Uri "$baseUrl/roles" -Method GET -Token $token

if ($rolesResult.Success) {
    Write-Success "获取角色列表成功"
    $roles = $rolesResult.Data
    if ($roles.data) {
        Write-Info "角色总数: $($roles.data.Count)"
        Write-Info "角色列表:"
        $roles.data | ForEach-Object {
            Write-Host "  - $($_.displayName) ($($_.name))" -ForegroundColor Gray
        }
    }
}
else {
    Write-Error "获取角色列表失败 (Status: $($rolesResult.StatusCode))"
}

Write-Info "`n测试: GET /permissions"
$permsResult = Invoke-ApiRequest -Uri "$baseUrl/permissions" -Method GET -Token $token

if ($permsResult.Success) {
    Write-Success "获取权限列表成功"
    Write-Info "权限总数: $($permsResult.Data.data.Count)"
}
else {
    Write-Error "获取权限列表失败 (Status: $($permsResult.StatusCode))"
}

# =====================================================
# 总结
# =====================================================
Write-Section "测试总结"

$successCount = 0
$failCount = 0

# 这里可以统计成功和失败的数量

Write-Host ""
Write-Info "测试完成时间: $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')"
Write-Host ""

if ($token) {
    Write-Success "✅ 认证成功，后端 API 正常运行"
}
else {
    Write-Error "❌ 认证失败，请检查后端配置"
    Write-Info ""
    Write-Info "可能的问题:"
    Write-Info "1. Spring Security 配置问题（CSRF、CORS）"
    Write-Info "2. 数据库密码哈希不匹配"
    Write-Info "3. JwtTokenProvider 配置问题"
    Write-Info "4. 端口或路径配置错误"
    Write-Info ""
    Write-Info "建议操作:"
    Write-Info "1. 查看后端控制台日志"
    Write-Info "2. 检查 application.yml 配置"
    Write-Info "3. 确认数据库连接正常"
    Write-Info "4. 使用 Postman 或其他工具测试"
}

Write-Host ""

